package com.ruoyi.business.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.business.domain.DocDirectory;
import com.ruoyi.business.domain.bo.PersonFileBo;
import com.ruoyi.business.domain.vo.DocDirectoryVo;
import com.ruoyi.business.domain.vo.PersonFileVo;
import com.ruoyi.business.service.IDocDirectoryService;
import com.ruoyi.business.service.IPersonFileService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.TreeBuildUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 档案目录Controller
 *
 * @author ruoyi
 * @date 2024-11-07
 */
@RestController
@RequestMapping("/business/directory")
public class DocDirectoryController extends BaseController {
    @Autowired
    private IDocDirectoryService docDirectoryService;
    @Autowired
    private IPersonFileService personFileService;

    /**
     * 查询档案目录列表
     */
    @PreAuthorize("@ss.hasPermi('business:directory:list')")
    @GetMapping("/list")
    public R<List<DocDirectoryVo>> list(DocDirectory docDirectory) {
        return R.ok(docDirectoryService.selectDocDirectoryList(docDirectory));
    }

    /**
     * 导出档案目录列表
     */
    @PreAuthorize("@ss.hasPermi('business:directory:export')")
    @Log(title = "档案目录", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public void export(DocDirectory docDirectory, HttpServletResponse response) {
        List<DocDirectoryVo> list = docDirectoryService.selectDocDirectoryList(docDirectory);
        ExcelUtil.exportExcel(list, "档案目录", DocDirectoryVo.class, response);
    }

    /**
     * 获取档案目录详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:directory:query')")
    @GetMapping(value = "/{id}")
    public R<DocDirectoryVo> getInfo(@PathVariable("id") Long id) {
        return R.ok(docDirectoryService.selectDocDirectoryById(id));
    }

    /**
     * 新增档案目录
     */
    @PreAuthorize("@ss.hasPermi('business:directory:add')")
    @Log(title = "档案目录", businessType = BusinessType.INSERT)
    @PostMapping
    public R<Void> add(@RequestBody DocDirectory docDirectory) {
        return toAjax(docDirectoryService.insertDocDirectory(docDirectory));
    }

    /**
     * 修改档案目录
     */
    @PreAuthorize("@ss.hasPermi('business:directory:edit')")
    @Log(title = "档案目录", businessType = BusinessType.UPDATE)
    @PutMapping
    public R<Void> edit(@RequestBody DocDirectory docDirectory) {
        return toAjax(docDirectoryService.updateDocDirectory(docDirectory));
    }

    /**
     * 删除档案目录
     */
    @PreAuthorize("@ss.hasPermi('business:directory:remove')")
    @Log(title = "档案目录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@PathVariable Long[] ids) {
        return toAjax(docDirectoryService.deleteDocDirectoryByIds(ids));
    }


    /**
     * 获取部门树列表
     */
    @SaCheckPermission("business:directory:list")
    @GetMapping("/tree")
    public R<List<Tree<Long>>> deptTree(DocDirectory docDirectory) {
        return R.ok(docDirectoryService.selectDeptTreeList(docDirectory));
    }


    @GetMapping("/top_and_leaf")
    public R<List<DocDirectoryVo>> list(Long personId) {
        List<DocDirectoryVo> list = docDirectoryService.selectDocDirectoryList(new DocDirectory());
        Map<Long, DocDirectoryVo> directoryMap = list.stream().collect(Collectors.toMap(DocDirectoryVo::getId, d -> d));
        List<Tree<Long>> treeList = TreeBuildUtils.build(list, (entity, tree) ->
                tree.setId(entity.getId())
                        .setParentId(entity.getParentId())
                        .setName(entity.getName())
                        .setWeight(entity.getId())
        );

        List<DocDirectoryVo> result = new ArrayList<>();
        Map<Long, List<PersonFileVo>> personFileMap = new HashMap<>();
        if (ObjectUtil.isNotNull(personId)) {
            // todo  查询人员档案上传状态
            List<PersonFileVo> personFileVos = personFileService.queryList(PersonFileBo.builder().personId(personId).build());

            for (PersonFileVo personFileVo : personFileVos) {
                if (!personFileMap.containsKey(personFileVo.getFileType())) {
                    personFileMap.put(personFileVo.getFileType(), new ArrayList<>());
                }
                personFileMap.get(personFileVo.getFileType()).add(personFileVo);
            }

            if (CollUtil.isNotEmpty(treeList)) {
                for (Tree<Long> tree : treeList) {
                    Long id = tree.getId();
                    DocDirectoryVo docDirectory = directoryMap.get(id);
                    docDirectory.setPersonId(personId);

                    if (tree.hasChild()) {
                        Map<Long, List<PersonFileVo>> finalPersonFileMap = personFileMap;

                        List<Long> childId = TreeBuildUtils.getLeafsNodes(tree.getChildren());
                        List<DocDirectoryVo> children = list.stream()
                                .filter(d -> childId.contains(d.getId()))
                                .peek(d -> {
                                    Long did = d.getId();
                                    List<PersonFileVo> personFileVo = finalPersonFileMap.get(did);
                                    d.setParentId(id);
                                    d.setPersonId(personId);
                                    d.fillByPersonFileVo(personFileVo);
                                })
                                .collect(Collectors.toList());
                        docDirectory.setChildren(children);
                    } else {
                        List<PersonFileVo> personFileVo = personFileMap.get(id);
                        DocDirectoryVo selfChild = ObjUtil.clone(docDirectory);
                        selfChild.setParentId(id);
                        selfChild.fillByPersonFileVo(personFileVo);
                        docDirectory.setChildren(CollUtil.newArrayList(selfChild));
                    }
                    result.add(docDirectory);
                }
            }
        }
        return R.ok(result);
    }
}
